home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / decomp / selectv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-01-23  |  4.0 KB  |  192 lines

  1. # include    <ingres.h>
  2. # include    <symbol.h>
  3. # include    <tree.h>
  4. # include    "globs.h"
  5. # include    <sccs.h>
  6.  
  7. SCCSID(@(#)selectv.c    8.1    12/31/84)
  8.  
  9. /*
  10. **  SELECTV -- Select a variable for substitution
  11. **
  12. **    Selectv is called to determinimume the "best" variable
  13. **    to substitute for. The algorithm used is based on
  14. **    the Wong/Youseffi paper ERL M78/17. Selectv returns
  15. **    the variable to be substituted or it returns -1 which
  16. **    indicates that there is a relation with no tuples.
  17. **    If there is only one variable left, it is of course
  18. **    the one choosen.
  19. **
  20. **    For cases of more than one variable, a variable with
  21. **    0 or 1 tuples will always be choosen. Otherwise the
  22. **    variable with the smallest "costfunction" will be selected.
  23. **    In case of a tie, the variable with the smallest tuple count
  24. **    is selected.
  25. **
  26. **    The costfunction is:
  27. **        |Ri|
  28. **           ______
  29. **        Peffective i
  30. **
  31. **    where |Ri| = cardinality of variable i.
  32. **    and   Peff = The number of pages needed to be accessed to
  33. **            safisfy a query on Ri assuminimumg all other
  34. **            variables have been substituted for.
  35. **
  36. **
  37. **    Peff is only an estimate. The estimate is based on the
  38. **    storage structure of Ri and on whether Ri is used in
  39. **    the target list. Considering only equality clauses,
  40. **    the relation's structure is examinimumed to see if any
  41. **    can be used effectively. The following assumptions are
  42. **    made:
  43. **        useful hash: Peff = 1
  44. **        useful isam: Peff = 2
  45. **        useful hash sec index: Peff = 2
  46. **        useful isam sec index: Peff = 3
  47. **
  48. **    If there is no useful structure or if the relation is
  49. **    a heap then:
  50. **        Peff = number of pages Ri occupies
  51. **    If the relation is not in the target list then its
  52. **    function is only an existence test. Scanning can and
  53. **    is stopped the first time a tuple is found which satisfies.
  54. **    We assume that on the average only 1/4 of the pages
  55. **    will have to be examinimumed.
  56. **
  57. **    Parameters:
  58. **        root - root of the query
  59. **
  60. **    Returns:
  61. **        The variable to substitute for
  62. **            or
  63. **        -1 if the query is false
  64. **
  65. **    Side Effects:
  66. **        can cause a relation to be opened since
  67. **        ckpkey needs to know the key structure.
  68. **
  69. **    Called By:
  70. **        decompy, decompz
  71. **
  72. **    Trace Flags:
  73. **        44
  74. */
  75.  
  76. selectv(root)
  77. register QTREE    *root;
  78. {
  79.     int                minimum, var, map, i;
  80.     register struct rang_tab    *rt, *rx;
  81.     long                costfunc(), lx, lt;
  82.  
  83.     map = root->sym.value.sym_root.lvarm | root->sym.value.sym_root.rvarm;
  84.  
  85.     minimum = -1;
  86.     lx = 0;
  87.     rx = NULL;
  88.  
  89.     for (i = 1, var = 0; map; i <<= 1, var++)
  90.     {
  91.         if ((map & i) == 0)
  92.             continue;
  93.  
  94.         map &= ~i;
  95.         rt = &De.de_rangev[var];
  96.         if (rx == NULL)
  97.         {
  98.             rx = rt;
  99.             minimum = var;
  100.             if (map == 0 || rt->rtcnt < 2)
  101.                 break;
  102.             lx = costfunc(root, var, rt);
  103.         }
  104.         else
  105.         {
  106.             if (rt->rtcnt < 2)
  107.             {
  108.                 rx = rt;
  109.                 minimum = var;
  110.                 break;
  111.             }
  112.  
  113.             lt = costfunc(root, var, rt);
  114.             if (lt < lx)
  115.             {
  116.                 rx = rt;
  117.                 minimum = var;
  118.                 lx = lt;
  119.             }
  120.         }
  121.     }
  122.  
  123.     if (minimum == -1)
  124.         syserr("selectv:no source var");
  125.  
  126. #    ifdef xDTR1
  127.     if (tTf(44, 1))
  128.     {
  129.         printf("selectv:%d,tups=%ld,", minimum, rx->rtcnt);
  130.         printf("cf=%ld,", lx);
  131.         nodepr(root);
  132.     }
  133. #    endif
  134.  
  135.     if (rx->rtcnt == 0)
  136.         minimum = -1;
  137.  
  138.     return (minimum);
  139. }
  140.  
  141.  
  142.  
  143. long
  144. costfunc(root, var, rx)
  145. QTREE        *root;
  146. int        var;
  147. struct rang_tab    *rx;
  148. {
  149.     register struct rang_tab    *r;
  150.     register int            i;
  151.     register char            *lp;
  152.     char                linkmap[MAXDOM];
  153.     long                rel_page(), l;
  154.     int                c_bug;
  155.  
  156.     r = rx;
  157.  
  158.     for (lp = linkmap, i = MAXDOM; i--; )
  159.         *lp++ = 0;
  160.     i = var;
  161.  
  162.     /*
  163.     ** The c-compiler does not know how to generate code
  164.     ** for the assignment of an short to a long inside
  165.     ** an "if" expression. Therefore the variable "c_bug"
  166.     ** is assigned the value of ckpkey inside the "if".
  167.     ** The value is assigned to "l" in the "else".
  168.     */
  169.     if (!findlinks(root, -1, i, linkmap) || (c_bug = ckpkey(linkmap, i)) == 0)
  170.     {
  171.         l = rel_pages(r->rtcnt, r->rtwid);
  172.  
  173.         /* if not in target list, assume 1/4 */
  174.         if ((root->sym.value.sym_root.lvarm & (01 << i)) == 0)
  175.         {
  176.             l >>= 2;
  177.             if (l == 0)
  178.                 l = 1;
  179.         }
  180.     }
  181.     else
  182.         l = c_bug;    /* l could not be assigned directly above */
  183.  
  184.     l = r->rtcnt / l;
  185.  
  186. #    ifdef xDTR1
  187.     if (tTf(44, 3))
  188.         printf("costfunc %d is %ld\n", i, l);
  189. #    endif
  190.     return (l);
  191. }
  192.